package com.zxing.ability;

import com.zxing.ResourceTable;
import com.zxing.camera.CameraManager;
import com.zxing.camera.ResultCallback;
import com.zxing.decoding.InactivityTimer;
import com.zxing.slice.CodeUtils;
import com.zxing.utils.Log;
import com.zxing.view.FinderSetting;
import com.zxing.view.ViewfinderView;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.DependentLayout;
import ohos.agp.components.Text;
import ohos.agp.components.surfaceprovider.SurfaceProvider;
import ohos.agp.graphics.Surface;
import ohos.agp.graphics.SurfaceOps;
import ohos.app.Context;
import ohos.app.Environment;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.global.resource.RawFileEntry;
import ohos.media.camera.CameraKit;
import ohos.media.camera.device.Camera;
import ohos.media.camera.device.CameraConfig;
import ohos.media.camera.device.CameraInfo;
import ohos.media.camera.device.CameraStateCallback;
import ohos.media.camera.device.FrameConfig;
import ohos.media.image.Image;
import ohos.media.image.ImageReceiver;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.ImageFormat;
import ohos.media.image.common.Rect;
import ohos.media.image.common.Size;
import ohos.media.player.Player;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.UUID;

import static ohos.media.camera.device.Camera.FrameConfigType.FRAME_CONFIG_PREVIEW;
import static ohos.media.camera.params.Metadata.FlashMode.FLASH_ALWAYS_OPEN;
import static ohos.media.camera.params.Metadata.FlashMode.FLASH_CLOSE;
import static ohos.media.camera.params.Metadata.FlashMode.FLASH_OPEN;

/**
 * 自定义布局 二维码扫描 ability
 */
public abstract class CaptureAbility extends Ability {

    private static final int SCREEN_WIDTH = 2340;
    private static final int SCREEN_HEIGHT = 1080;
    private static final int IMAGE_RCV_CAPACITY = 5;
    private ImageReceiver imageReceiver;
    private Camera cameraDevice;
    private Surface previewSurface;
    private EventHandler creamEventHandler;
    private boolean isOpen = true;
    private FrameConfig.Builder framePreviewConfigBuilder;
    private FinderSetting setting;
    private CodeUtils.AnalyzeCallback analyzeCallback;
    private boolean isShowTopBar = true;
    private DependentLayout topBar;
    private boolean isSound = true;
    private Player player;
    private Context context;
    private SurfaceProvider surfaceProvider = null;
    private boolean isOn =false;
    private ViewfinderView viewfinderView;

    /**
     * 扫描监听
     *
     * @param analyzeCallback 回调
     */
    public void setResultCallback(CodeUtils.AnalyzeCallback analyzeCallback) {
        this.analyzeCallback = analyzeCallback;
    }

    /**
     * 初始化，必须在setContentView之后
     *
     * @param context 上下文
     * @param surfaceView  surfaceView
     * @param viewfinderView 框
     */
    protected void init(Ability context, SurfaceProvider surfaceView, ViewfinderView viewfinderView) {
        this.context = context;
        this.surfaceProvider = surfaceView;
        this.viewfinderView = viewfinderView;

        if (creamEventHandler == null) {
            creamEventHandler = new EventHandler(EventRunner.create("CameraBackground"));
        }
        if (isSound) {
            initBeepSound();
        }

        CameraManager.init(getApplicationContext());

        creamEventHandler.postTask(new Runnable() {
            @Override
            public void run() {
                initSurface();
            }
        });
    }


    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        getWindow().setTransparent(true);

    }

    protected final boolean isOn() {
        return isOn;
    }

    /**
     * 打开或关闭闪关灯
     *
     * @param on 是否打开
     */
    protected void switchLight(boolean on) {
        this.isOn = on;
        this.isOn = CameraManager.get().switchLight(on);
    }


    /**
     * 初始化surface
     */
    protected void initSurface() {
        if (surfaceProvider == null) {
            return;
        }
        surfaceProvider.pinToZTop(false);
        if (surfaceProvider != null) {
            surfaceProvider.getSurfaceOps().get().addCallback(new SurfaceCallBack());
        }
    }


    /**
     * SurfaceCallBack
     *
     * @since 2020-09-03
     */
    class SurfaceCallBack implements SurfaceOps.Callback {
        @Override
        public void surfaceCreated(SurfaceOps callbackSurfaceOps) {
            if (callbackSurfaceOps != null) {
                callbackSurfaceOps.setFixedSize(SCREEN_WIDTH, SCREEN_HEIGHT);
            }
            openCamera();
        }

        @Override
        public void surfaceChanged(SurfaceOps callbackSurfaceOps, int format, int width, int height) {
        }

        @Override
        public void surfaceDestroyed(SurfaceOps callbackSurfaceOps) {
        }
    }

    /**
     * 初始化并打开摄像头
     */
    protected void openCamera() {
        try {
            CameraManager.get().openDriver(surfaceProvider, creamEventHandler,viewfinderView,new ResultCallback(){
                @Override
                public void resultDecode(String result, PixelMap barcode) {
                    handleDecode(result, barcode);
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    private void initBeepSound() {
        try {
            player = new Player(this);

            String data = getResourceManager().getMediaPath(ResourceTable.Media_beep);
            RawFileEntry fileEntry = getResourceManager().getRawFileEntry(data);
            player.setSource(fileEntry.openRawFileDescriptor());

            player.setVolume(0.10f);
            player.prepare();
        } catch (Exception e) {
            Log.error(e.getMessage());
        }
    }

    /**
     * scan result
     * @param result 返回结果
     * @param barcode code
     */
    public void handleDecode(String result,PixelMap barcode) {
        if (isSound && player != null) {
            player.play();
        }

        if (analyzeCallback != null) {
            analyzeCallback.onAnalyzeSuccess(barcode, result);
        }
        Intent intent = new Intent();
        intent.setParam("result", result);
        setResult(1, intent);
        terminateAbility();
    }

    /**
     * 获取handler
     * @return creamEventHandler
     */
    public EventHandler getHandle() {
        return creamEventHandler;
    }

    @Override
    protected void onStop() {
        super.onStop();
        CameraManager.get().closeDriver();
        if (creamEventHandler != null) {
            creamEventHandler.removeAllEvent();
        }
    }
}
